package com.tzstcl.gen.ctrl;

import com.tzstcl.commons.utils.StringUtils;
import com.tzstcl.gen.model.GenTable;
import com.tzstcl.gen.model.GenTableColumn;
import com.tzstcl.gen.service.impl.GenerateServiceImpl;
import com.tzstcl.gen.util.Folder;
import com.tzstcl.gen.util.GenUtils;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.net.URLDecoder;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 公司：天筑科技股份有限公司
 * 作者：zgq
 * 日期：2018年09月05日
 * 说明：
 */
public class GenCodeCtrl {
    public static void main(String[] args) {
        GenTable genTable = new GenTable();
        genTable.setAuthor("xj");
        genTable.setCurrentDate(new Date());
        genTable.setClassName("Newtbdesigneconuserinfo");
        genTable.setUnClassName(StringUtils.uncapitalize(genTable.getClassName()));
        genTable.setTableName("new_tbdesigneconuserinfo");
        String basePackage = "com.tzstcl";
        genTable.setModuleName("sikupingtai");
        genTable.setSubModuleName("provinceMid");
        genTable.setPackageName(basePackage + "." + genTable.getModuleName() + "." + genTable.getSubModuleName());
        genTable.setFunctionName("专业技术人员明细表");
        genTable.setFunctionNameSimple("专业技术人员明细表");
        genTable.setPermissionPrefix(genTable.getModuleName() + (StringUtils.isNotBlank(genTable.getSubModuleName())
                ? ":" + StringUtils.lowerCase(genTable.getSubModuleName()) : "") + ":" + genTable.getUnClassName());
        genTable.setColumns(getAll(genTable.getTableName()));
        if (null != genTable.getColumns() && genTable.getColumns().size() > 0) {
            GenUtils.initColumnField(genTable);
            System.out.println(new GenerateServiceImpl().create(genTable).equals("status:0") ? "代码生成成功！" : "代码生成失败！");
        } else {
            System.out.println("代码生成失败！");
        }
    }

    public String create(GenTable genTable) {

        Folder folder = new Folder();
        String packageName = genTable.getPackageName();
        String className = genTable.getClassName();
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_25);
        String path = GenCodeCtrl.class.getResource("/").getPath() + "templates/gen/curd";
        path = path.substring(1);
//        System.out.println(path);
        try {
            cfg.setDirectoryForTemplateLoading(new File(URLDecoder.decode(path, "UTF-8")));//模版路径
            Template templateEntity = cfg.getTemplate("/entity.ftl");//entity层
            Template templateMapper = cfg.getTemplate("/mapper.ftl");//dao层
            Template templateService = cfg.getTemplate("/service.ftl");//service层
            Template templateServiceImpl = cfg.getTemplate("/serviceImpl.ftl");//service层
            Template templateCtrl = cfg.getTemplate("/ctrl.ftl");//web层
            Template templateXml = cfg.getTemplate("/xml.ftl");//xml层
            Template templateViewList = cfg.getTemplate("/viewList.ftl");//页面
            Template templateViewForm = cfg.getTemplate("/viewForm.ftl");//页面
            StringWriter entity = new StringWriter();
            StringWriter dao = new StringWriter();
            StringWriter service = new StringWriter();
            StringWriter serviceImpl = new StringWriter();
            StringWriter ctrl = new StringWriter();
            StringWriter xml = new StringWriter();
            StringWriter viewList = new StringWriter();
            StringWriter viewForm = new StringWriter();
            templateEntity.process(genTable, entity);
            templateMapper.process(genTable, dao);
            templateService.process(genTable, service);
            templateServiceImpl.process(genTable, serviceImpl);
            templateCtrl.process(genTable, ctrl);
            templateXml.process(genTable, xml);
            templateViewList.process(genTable, viewList);
            templateViewForm.process(genTable, viewForm);
            String entityName = folder.folder(packageName + ".model", "1");//生成文件夹实体层
            String mapperName = folder.folder(packageName + ".mapper", "1");//生成文件夹dao层
            String serviceName = folder.folder(packageName + ".service", "1");//生成文件夹service层
            String serviceImplName = folder.folder(packageName + ".service.impl", "1");//生成文件夹serviceImpl层
            String ctrlName = folder.folder(packageName + ".ctrl", "1");//生成文件夹controller层
            String xmlName = folder.folder(packageName + ".mapper", "2");//生成文件夹mapping xml文件层

            String viewListName = folder.folder(genTable.getModuleName() + "." + genTable.getSubModuleName(), "3");//生成文件夹页面层
            //对应生成文件
            String entitys = className + ".java";
            String daos = className + "Mapper.java";
            String services = className + "Service.java";
            String serviceImpls = className + "ServiceImpl.java";
            String ctrls = className + "Ctrl.java";
            String xmls = className + "Mapper.xml";
            String viewListstr = genTable.getUnClassName() + "List.html";
            String viewFormstr = genTable.getUnClassName() + "Form.html";
            try {
                FileWriter fwEntity = new FileWriter(entityName + "\\" + entitys, false);  // FileWriter 就是牛，如果文件名 的文件不存在，先创建再读写;存在的话直接追加写,关键字true表示追加
                fwEntity.write(String.valueOf(entity));
                fwEntity.close(); // 关闭写文件,每次仅仅写一行数据，因为一个读文件中仅仅一个唯一的od
                FileWriter fwMapper = new FileWriter(mapperName + "\\" + daos, false);
                fwMapper.write(String.valueOf(dao));
                fwMapper.close();
                FileWriter fwService = new FileWriter(serviceName + "\\" + services, false);
                fwService.write(String.valueOf(service));
                fwService.close();
                FileWriter fwServiceImpl = new FileWriter(serviceImplName + "\\" + serviceImpls, false);
                fwServiceImpl.write(String.valueOf(serviceImpl));
                fwServiceImpl.close();
                FileWriter fwCtrl = new FileWriter(ctrlName + "\\" + ctrls, false);
                fwCtrl.write(String.valueOf(ctrl));
                fwCtrl.close();
                FileWriter fwXml = new FileWriter(xmlName + "\\" + xmls, false);
                fwXml.write(String.valueOf(xml));
                fwXml.close();
                FileWriter fwViewList = new FileWriter(viewListName + "\\" + viewListstr, false);
                fwViewList.write(String.valueOf(viewList));
                fwViewList.close();
                FileWriter fwViewForm = new FileWriter(viewListName + "\\" + viewFormstr, false);
                fwViewForm.write(String.valueOf(viewForm));
                fwViewForm.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return "status:" + "0";
        } catch (IOException e) {
            e.printStackTrace();
            return "status:" + "1";
        } catch (TemplateException e) {
            e.printStackTrace();
            return "status:" + "1";
        }
    }

    private static Connection getConn() {
        String driver = "com.mysql.jdbc.Driver";
        String url = "jdbc:mysql://localhost:3306/middle_prj?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8";
        String username = "root";
        //String password = "root.";
        String password = "123456";
        Connection conn = null;
        try {
            Class.forName(driver); //classLoader,加载对应驱动
            conn = (Connection) DriverManager.getConnection(url, username, password);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }

    private static List<GenTableColumn> getAll(String tableName) {
        List<GenTableColumn> columns = new ArrayList<>();
        Connection conn = getConn();
        String sql = "SELECT t.COLUMN_NAME AS name, (CASE WHEN t.IS_NULLABLE = 'YES' THEN '1' ELSE '0' END) AS isNull,(t.ORDINAL_POSITION * 10) AS sort,t.COLUMN_COMMENT AS comments,t.COLUMN_TYPE AS jdbcType FROM information_schema.`COLUMNS` t WHERE t.TABLE_SCHEMA = (select database()) AND t.TABLE_NAME = upper('" + tableName + "')";
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();
            int col = rs.getMetaData().getColumnCount();
//            System.out.println("============================");
            while (rs.next()) {
                GenTableColumn idColumn = new GenTableColumn();//id
                idColumn.setName(rs.getString(1));
                idColumn.setIsNull(rs.getString(2));
                idColumn.setSort(Integer.valueOf(rs.getString(3)));
                idColumn.setComments(rs.getString(4));
                idColumn.setJdbcType(rs.getString(5));
                columns.add(idColumn);
            }
//            System.out.println("============================");
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if(null != rs){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(null != pstmt){
                try {
                    pstmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return columns;
    }
}
